
// flow_control_test

pub fn flow_control_test(){
    flow_control_test_ifelse();
    flow_control_test_loop();
    flow_control_test_loop2();
    flow_control_test_loop3();
    flow_control_test_while();
    flow_control_test_for_loops();
    flow_control_test_for_and_range();
    flow_control_test_for_and_iterators();
}

fn flow_control_test_ifelse() {
    let n = 5;

    if n < 0 {
        print!("{} is negative", n);
    } else if n > 0 {
        print!("{} is positive", n);
    } else {
        print!("{} is zero", n);
    }

    let big_n =
        if n < 10 && n > -10 {
            println!(", and is a small number, increase ten-fold");

            // This expression returns an `i32`.
            10 * n
        } else {
            println!(", and is a big number, half the number");

            // This expression must return an `i32` as well.
            n / 2
            // TODO ^ Try suppressing this expression with a semicolon.
        };
    //   ^ Don't forget to put a semicolon here! All `let` bindings need it.

    println!("{} -> {}", n, big_n);
}

fn flow_control_test_loop() {
    let mut count = 0u32;

    println!("Let's count until infinity!");

    // Infinite loop
    loop {
        count += 1;

        if count == 3 {
            println!("three");

            // Skip the rest of this iteration
            continue;
        }

        println!("{}", count);

        if count == 5 {
            println!("OK, that's enough");

            // Exit this loop
            break;
        }
    }
}

// Nesting and labels
// #![allow(unreachable_code)]
// #![warn(unreachable_code)]

fn flow_control_test_loop2() {
    let mut i:i32 = 0i32;
    'outer: loop {
        println!("曾经报错的外部循环：Entered the outer loop");

        'inner: loop {
            println!("曾经报错的内循环：Entered the inner loop");
            i += 1;
            // This would break only the inner loop
            //break;

            // This breaks the outer loop
            break 'outer;
        }
        
        println!("This point will never be reached");
        if i >= 5 {
            break;
        }
    }

    println!("Exited the outer loop");
}


// Returning from loops
fn flow_control_test_loop3() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    assert_eq!(result, 20);
}


// while
fn flow_control_test_while() {
    // A counter variable
    let mut n = 1;

    // Loop while `n` is less than 101
    while n < 101 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        } else if n % 5 == 0 {
            println!("buzz");
        } else {
            println!("{}", n);
        }

        // Increment counter
        n += 1;
    }
}

// for loops
// for and range
fn flow_control_test_for_loops() {
    // `n` will take the values: 1, 2, ..., 100 in each iteration
    for n in 1..101 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        } else if n % 5 == 0 {
            println!("buzz");
        } else {
            println!("{}", n);
        }
    }
}

fn flow_control_test_for_and_range() {
    // `n` will take the values: 1, 2, ..., 100 in each iteration
    for n in 1..=100 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        } else if n % 5 == 0 {
            println!("buzz");
        } else {
            println!("{}", n);
        }
    }
}

// for and iterators

fn flow_control_test_for_and_iterators() {
    let names = vec!["Bob", "Frank", "Ferris"];

    for name in names.iter() {
        match name {
            &"Ferris" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }

    let names = vec!["Bob", "Frank", "Ferris"];

    for name in names.into_iter() {
        match name {
            "Ferris" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }

    let mut mut_names = vec!["Bob", "Frank", "Ferris"];

    for name in mut_names.iter_mut() {
        match name {
            &mut "Ferris" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }
}